home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / DEMOS / underwater / DINO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  4.4 KB  |  130 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994, 1997.  */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. #include <stdlib.h>
  9. #include <math.h>       /* for sqrt() */
  10. #include <GL/glut.h>
  11.  
  12. #include "dino.h"
  13.  
  14. typedef enum {
  15.   RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE,
  16.   LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE, DINOSAUR
  17. } displayLists;
  18.  
  19. /* *INDENT-OFF* */
  20. static GLfloat body[][2] = { {0, 3}, {1, 1}, {5, 1}, {8, 4}, {10, 4}, {11, 5},
  21.   {11, 11.5}, {13, 12}, {13, 13}, {10, 13.5}, {13, 14}, {13, 15}, {11, 16},
  22.   {8, 16}, {7, 15}, {7, 13}, {8, 12}, {7, 11}, {6, 6}, {4, 3}, {3, 2},
  23.   {1, 2} };
  24. static GLfloat arm[][2] = { {8, 10}, {9, 9}, {10, 9}, {13, 8}, {14, 9}, {16, 9},
  25.   {15, 9.5}, {16, 10}, {15, 10}, {15.5, 11}, {14.5, 10}, {14, 11}, {14, 10},
  26.   {13, 9}, {11, 11}, {9, 11} };
  27. static GLfloat leg[][2] = { {8, 6}, {8, 4}, {9, 3}, {9, 2}, {8, 1}, {8, 0.5}, {9, 0},
  28.   {12, 0}, {10, 1}, {10, 2}, {12, 4}, {11, 6}, {10, 7}, {9, 7} };
  29. static GLfloat eye[][2] = { {8.75, 15}, {9, 14.7}, {9.6, 14.7}, {10.1, 15},
  30.   {9.6, 15.25}, {9, 15.25} };
  31. static GLfloat skinColor[] = {0.1, 1.0, 0.1, 1.0}, eyeColor[] = {1.0, 0.2, 0.2, 1.0};
  32. /* *INDENT-ON* */
  33.  
  34. static void
  35. extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize,
  36.   GLdouble thickness, GLuint side, GLuint edge, GLuint whole)
  37. {
  38.   static GLUtriangulatorObj *tobj = NULL;
  39.   GLdouble vertex[3], dx, dy, len;
  40.   int i;
  41.   int count = (int) (dataSize / (2 * sizeof(GLfloat)));
  42.  
  43.   if (tobj == NULL) {
  44.     tobj = gluNewTess();  /* create and initialize a GLU
  45.                              polygon tesselation object */
  46.     gluTessCallback(tobj, GLU_BEGIN, glBegin);
  47.     gluTessCallback(tobj, GLU_VERTEX, glVertex2fv);  /* semi-tricky */
  48.     gluTessCallback(tobj, GLU_END, glEnd);
  49.   }
  50.   glNewList(side, GL_COMPILE);
  51.   glShadeModel(GL_SMOOTH);  /* smooth minimizes seeing
  52.                                tessellation */
  53.   gluBeginPolygon(tobj);
  54.   for (i = 0; i < count; i++) {
  55.     vertex[0] = data[i][0];
  56.     vertex[1] = data[i][1];
  57.     vertex[2] = 0;
  58.     gluTessVertex(tobj, vertex, data[i]);
  59.   }
  60.   gluEndPolygon(tobj);
  61.   glEndList();
  62.   glNewList(edge, GL_COMPILE);
  63.   glShadeModel(GL_FLAT);  /* flat shade keeps angular hands
  64.                              from being "smoothed" */
  65.   glBegin(GL_QUAD_STRIP);
  66.   for (i = 0; i <= count; i++) {
  67.     /* mod function handles closing the edge */
  68.     glVertex3f(data[i % count][0], data[i % count][1], 0.0);
  69.     glVertex3f(data[i % count][0], data[i % count][1], thickness);
  70.     /* Calculate a unit normal by dividing by Euclidean
  71.        distance. We * could be lazy and use
  72.        glEnable(GL_NORMALIZE) so we could pass in * arbitrary
  73.        normals for a very slight performance hit. */
  74.     dx = data[(i + 1) % count][1] - data[i % count][1];
  75.     dy = data[i % count][0] - data[(i + 1) % count][0];
  76.     len = sqrt(dx * dx + dy * dy);
  77.     glNormal3f(dx / len, dy / len, 0.0);
  78.   }
  79.   glEnd();
  80.   glEndList();
  81.   glNewList(whole, GL_COMPILE);
  82.   glFrontFace(GL_CW);
  83.   glCallList(edge);
  84.   glNormal3f(0.0, 0.0, -1.0);  /* constant normal for side */
  85.   glCallList(side);
  86.   glPushMatrix();
  87.   glTranslatef(0.0, 0.0, thickness);
  88.   glFrontFace(GL_CCW);
  89.   glNormal3f(0.0, 0.0, 1.0);  /* opposite normal for other side */
  90.   glCallList(side);
  91.   glPopMatrix();
  92.   glEndList();
  93. }
  94.  
  95. int
  96. makeDinosaur(void)
  97. {
  98.   GLfloat bodyWidth = 3.0;
  99.  
  100.   extrudeSolidFromPolygon(body, sizeof(body), bodyWidth,
  101.     BODY_SIDE, BODY_EDGE, BODY_WHOLE);
  102.   extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4,
  103.     ARM_SIDE, ARM_EDGE, ARM_WHOLE);
  104.   extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2,
  105.     LEG_SIDE, LEG_EDGE, LEG_WHOLE);
  106.   extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2,
  107.     EYE_SIDE, EYE_EDGE, EYE_WHOLE);
  108.   glNewList(DINOSAUR, GL_COMPILE);
  109.   glPushMatrix();
  110.   glTranslatef(-8, -8, -bodyWidth / 2);
  111.   glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);
  112.   glCallList(BODY_WHOLE);
  113.   glPushMatrix();
  114.   glTranslatef(0.0, 0.0, bodyWidth);
  115.   glCallList(ARM_WHOLE);
  116.   glCallList(LEG_WHOLE);
  117.   glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4);
  118.   glCallList(ARM_WHOLE);
  119.   glTranslatef(0.0, 0.0, -bodyWidth / 4);
  120.   glCallList(LEG_WHOLE);
  121.   glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1);
  122.   glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);
  123.   glCallList(EYE_WHOLE);
  124.   glPopMatrix();
  125.   glPopMatrix();
  126.   glEndList();
  127.   return DINOSAUR;
  128. }
  129.  
  130.